#include "../header.h"

union semnum
{
    int value;
};
//定义变量 = 1  ; 
union  semnum value = {1};

//1.双进程
//2.公共资源
//3.信号量

int main(int argc, char const *argv[])
{
    //公共资源。
    int fd = open("aaa.txt",O_CREAT | O_APPEND | O_RDWR,0666);

    //准备信号量
    //路径数值 + 50 -> 合成一个唯一数值
    key_t key = ftok(".",60);
    if(key < 0)
    {
        perror("键值生成失败!\n");
        return -1;
    }
    printf("键值生成成功:%d\n",key);

    //生成信号量
    //创建一个信号量 指定访问权限
    int semid = semget(key,1,IPC_CREAT|0600);
    if(semid < 0)
    {
        perror("semid error\n");
        return -2;
    }
    //打印信号量id值
    printf("semid = %d\n",semid);
    //初始化信号量
    semctl(semid,0,SETVAL,value);
    //获取信号量初值
    int res = semctl(semid,0,GETVAL,0);
    printf("返回值就是信号量初值:%d\n",res);

    //双任务
    pid_t pid = fork();
    if(pid < 0)
        exit(-1);
    //父进程空间
    if(pid > 0)
    {
        //p操作
        //p操作
        struct sembuf buf = {0};
        buf.sem_num = 0 ; 
        buf.sem_flg = 0 ;
        //p操作 
        buf.sem_op = -1;
        if(semop(semid,&buf,1) < 0 )
        {
            perror("p操作失败!\n");
        }
        int num = 5;
        //独占公共数据
        char * str = "this is parents process\n";
        while(num--)
        {
            write(fd,str,strlen(str));
            sleep(1);
        }
        //v操作
        buf.sem_op = +1;
        if(semop(semid,&buf,1) < 0 )
        {
            perror("v操作失败!\n");
        }
        printf("this is parents process:%d\n",getpid());
        wait(NULL);
        //删除信号量
        semctl(semid,0,IPC_RMID,0);
    }
    if (pid == 0)
    {
        //p操作
        //p操作
        struct sembuf buf = {0};
        buf.sem_num = 0 ; 
        buf.sem_flg = 0 ;
        //p操作 
        buf.sem_op = -1;
        if(semop(semid,&buf,1) < 0 )
        {
            perror("p操作失败!\n");
        }
        //独占公共数据
        char *str1 = "this is child parents!\n";
        int num = 5;
        while(num--)
        {
            write(fd,str1,strlen(str1));
            sleep(1);
        }
        //v操作
            buf.sem_op = +1;
        if(semop(semid,&buf,1) < 0 )
        {
            perror("v操作失败!\n");
        }
        /* code */
        printf("this is child process:%d\n",getpid());
    }
    close(fd);
    return 0;
}
